package mutli_cache

import (
	jsoniter "github.com/json-iterator/go"
	"time"
)

var (
	EntryLazyFactor = 32
)

type Entry struct {
	Value      interface{} `json:"value"`      // 数据
	TtlSecond  int         `json:"ttl"`        // 过期时间段,x秒
	Obsolete   int64       `json:"obsolete"`   // 失效时间,本地缓存使用
	Expiration int64       `json:"expiration"` // 过期时间,外部数据源使用
}

// Obsoleted 判断本地数据源数据是否需要更新
func (e *Entry) Obsoleted() bool {
	// 如果失效时间小于0,则失效
	if e.Obsolete <= 0 {
		return true
	}
	// 如果当前时间大于失效时间则失效
	if e.Obsolete < time.Now().Unix() {
		return true
	}
	// 未失效
	return false
}

// GetObsoleteTTL 获取失效时间
func (e *Entry) GetObsoleteTTL() (second int64) {
	return e.Obsolete - time.Now().Unix()
}

// Expired  外部数据源数据是否过期
func (e *Entry) Expired() bool {
	// 过期时间小于0,失效
	if e.Expiration <= 0 {
		return true
	}
	// 过期失效小于当前时间,则失效
	if e.Expiration < time.Now().Unix() {
		return true
	}
	// 过期时间大于当前时间,未失效
	return false
}

// GetExpireTTL 获取过期时间
func (e *Entry) GetExpireTTL() (second int64) {
	return e.Expiration - time.Now().Unix()
}

func (e *Entry) String() string {
	s, _ := jsoniter.MarshalToString(e.Value)
	return s
}

// NewEntry 创建数据对象,包含过期时间
func NewEntry(v interface{}, second int) *Entry {
	ttl := second
	var od, e int64
	if second > 0 {
		// 本地数据源过期时间second秒
		od = time.Now().Add(time.Duration(second) * time.Second).Unix()
		// 外部数据源过期时间32*second秒
		e = time.Now().Add(time.Duration(second*EntryLazyFactor) * time.Second).Unix()
	}
	return &Entry{
		Value:      v,
		TtlSecond:  ttl,
		Obsolete:   od,
		Expiration: e,
	}
}
